local upstream = require "ngx.upstream"
local http = require "resty.http"
local cjson = require "cjson"
local get_servers = upstream.get_servers
local get_upstreams = upstream.get_upstreams
local us = get_upstreams()
local hc = http:new()
local cj = cjson.new()
local Config = require("config")
local limit = ngx.shared.limit

local enable = Config.enable
local healthyInterval = Config.healthyInterval
local healthyRequestTimeout = Config.healthyRequestTimeout
local healthyRequestUrl = Config.healthyRequestUrl
local healthyRequestMethod = Config.healthyRequestMethod
local healthyBedInterval = Config.healthyBedInterval
local healthySendSmsMobiles = Config.healthySendSmsMobiles
local healthySendSmsUrl = Config.healthySendSmsUrl
local healthySendSmsInterval = Config.healthySendSmsInterval
local healthyExclude = Config.healthyExclude

local array_indexOf = function(data,list)
	for _, l in ipairs(list) do 
		if l == data then
			return _
		end
	end
	return -1
end



--val1 工程名,val2 节点地址
local send_sms = function(val1,val2) 
	for _, m in ipairs(healthySendSmsMobiles) do
		local k = m..val2;
		if limit:get(k) == nil then
			local l = string.format(healthySendSmsUrl,m,val1,val2);
			local ok, code, headers, status, body  = hc:request {
				url = l,
				method = "GET",
				timeout = healthyRequestTimeout
			}
			if code == 200 then
				limit:set(k,true,healthySendSmsInterval)
			end
		end
	end
end

local check_upstreams = function(addr)
	local req,_=limit:get(addr)
	if req ~= nil then
	    return req
	end
	local ok, code, headers, status, body  = hc:request {
        url = "http://"..addr..healthyRequestUrl,
        method = healthyRequestMethod,
		timeout = healthyRequestTimeout
    }
	ngx.log(ngx.ERR,addr .. " " .. code);
	if ok and code == 200 and body ~= nil then
	    local json = cj.decode(body);
		if json.status.code=="UP" then
			limit:set(addr,true,healthyInterval)
			return true;
		end
		ngx.log(ngx.ERR,addr .. " body:" .. body);
	end
	limit:set(addr,false,healthyBedInterval)
	return false;
end

if enable then
	for _, u in ipairs(us) do
		if array_indexOf(u,healthyExclude) == -1 then
			local srvs, err = get_servers(u)
			if not srvs then
				ngx.log(ngx.ERR,"failed to get servers in upstream "..u)
			else
				for _, srv in ipairs(srvs) do
					local isdown = false
					local host = nil				
					for k, v in pairs(srv) do
						if k=="addr" then
							host = v
							isdown = (not check_upstreams(v.."/"..u))
						end
					end
					upstream.set_peer_down(u, false, (_-1), isdown)
					if isdown then 
						send_sms(u,host)
					end
				end
			end
		end
	end
end
